package pro.cherish.smartfile.config;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 应用上下文
 */
@Component
public class AppContext implements ApplicationContextAware {
    /**
     * 线程域
     */
    private static final ThreadLocal<Map<String, Object>> localMap = ThreadLocal.withInitial(HashMap::new);
    /**
     * spring 容器上下文
     */
    private static ApplicationContext applicationContext;
    /**
     * 环境配置
     */
    private static ConfigurableEnvironment environment;
    private static Map<String, Object> globalMap = new ConcurrentHashMap<>(20);

    /**
     * 获取spring 容器
     *
     * @param
     * @Return org.springframework.context.ApplicationContext
     * @Author lys
     * @Date 2020-5-29 13:21
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        AppContext.applicationContext = applicationContext;
    }

    /**
     * 根据ID获取Bean
     *
     * @param id Bean ID
     * @Return Object
     * @Author lys
     * @Date 2020-5-29 13:21
     */
    public static <T> T getBean(String id) {
        return (T) applicationContext.getBean(id);
    }

    /**
     * 根据字节码类型获取Bean
     *
     * @param clazz Bean 字节码类型
     * @Return T
     * @Author lys
     * @Date 2020-5-29 13:22
     */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    /**
     * 是否包含Bean
     *
     * @param name Bean 名称
     * @Return boolean
     * @Author lys
     * @Date 2020-5-29 13:24
     */
    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    /**
     * 是否单例
     *
     * @param name Bean 名称
     * @Return boolean
     * @Author lys
     * @Date 2020-5-29 13:25
     */
    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }

    public static <T> T get(String key) {
        return globalMap.get(key) != null ? (T) globalMap.get(key) : null;
    }

    /**
     * 获取指定键名的变量值
     *
     * @param key 键名
     * @Return java.lang.Object
     * @Author lys
     * @Date 2020-6-2 15:08
     */
    public static <T> T getLocal(String key) {
        Map<String, Object> map = localMap.get();
        return map.get(key) != null ? (T) map.get(key) : null;
    }

    /**
     * 设置键值对到线程域
     *
     * @param keyValueMap 键值对
     * @Return void
     * @Author lys
     * @Date 2020-6-2 15:07
     */
    public static void putLocalAll(Map<String, Object> keyValueMap) {
        localMap.get().putAll(keyValueMap);
    }

    /**
     * 获取指定键名的变量值，无则取默认值
     *
     * @param key          键名
     * @param defaultValue 默认值
     * @Return java.lang.Object
     * @Author lys
     * @Date 2020-6-2 15:08
     */
    public static <T> T getLocal(String key, T defaultValue) {
        Map<String, Object> map = localMap.get();
        return map.get(key) == null ? defaultValue : (T) map.get(key);
    }

    /**
     * 设置到全局变量
     *
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        globalMap.put(key, value);
    }

    /**
     * 设置键值对到线程域
     *
     * @param key   键
     * @param value 值
     * @Return void
     * @Author lys
     * @Date 2020-6-2 15:08
     */
    public static void setLocal(String key, Object value) {
        localMap.get().put(key, value);
    }


    public static ConfigurableEnvironment getEnvironment() {
        return environment;
    }

    public static void setEnvironment(ConfigurableEnvironment env) {
        environment = env;
    }

}

